package com.example.chess2;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.EmbossMaskFilter;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.widget.ImageView;

public class MyImageView extends ImageView {

	private Paint mPaint,wPaint,bPaint,paint,fPaint;
	
	private Bitmap go_w,go_b;
	
	private Path mPath = new Path();
	
//	private int radius = 10;  //半径
	
	private int radius;  //半径
	
	private float x,y;  //点击坐标

	private int width,height;  //屏幕宽高
	
	private int xoffset,yoffset,offset;
	
	private int padTop,padLeft,padRight,padBottom;
	 
	private Point[][] matrix;  //交点矩阵
	
	private int[][] temp;   //
	
	private Point[][] isPaint;  //哪些点已经有子
	
	private List<PPoint> pPoints;  //下子链表
	
	private List<PPoint> delPoints;  //删除列表
	
	private int rows,columns; //行数和列数
	
	private int px,py;   //点击后的行数和列数
	
	private int k = 0;  //哪一步
	
	private List<Piece> pieces;   //所有的块数
	
	private int left,right,top,bottom;  //上下左右边距
	
	private boolean isKo = false;
	
	private boolean down = false;
	
	public interface LockScreenLayoutListener {
		public void onUnLock();
	}

	public MyImageView(Context context) {
		this(context, null);
		Log.i("MyImageView1", "1");
	}

	public MyImageView(Context context, AttributeSet attrs) {
		this(context, attrs,0);
		Log.i("MyImageView2", "2");
	    init();
	}
	
	private void init(){

	    WindowManager wm=(WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
	    width=wm.getDefaultDisplay().getWidth();//
	    height=wm.getDefaultDisplay().getHeight();//
	    Log.i("RC", width + ":" + height);
	    
	    float[] dire = new float[]{1,1,1};  //光线方向
		float light = 0.5f;   //光线强度
		float spe = 6;
		float blur = 3.5f;
		EmbossMaskFilter emboss=new EmbossMaskFilter(dire,light,spe,blur);
	    
	    
	    fPaint = new Paint();
		fPaint.setColor(Color.RED);
		fPaint.setStyle(Paint.Style.FILL);  
		fPaint.setAntiAlias(true);
		
		go_w = BitmapFactory.decodeResource(this.getContext().getResources(), R.drawable.go_white);
		go_b = BitmapFactory.decodeResource(this.getContext().getResources(), R.drawable.go_black);
		
		
		mPaint = new Paint();
		mPaint.setColor(Color.BLUE);
		mPaint.setStyle(Paint.Style.FILL); 
		mPaint.setAntiAlias(true);
	    
	    wPaint = new Paint();
	    wPaint.setColor(Color.WHITE);
	    wPaint.setStyle(Paint.Style.FILL); 
	    wPaint.setAntiAlias(true);
	    wPaint.setMaskFilter(emboss);
	    
	    bPaint = new Paint();
	    bPaint.setColor(Color.BLACK);
	    bPaint.setStyle(Paint.Style.FILL); 
	    bPaint.setAntiAlias(true);
	    bPaint.setMaskFilter(emboss);
	    
	    paint = mPaint;
	    
	    padTop=padBottom = 90;
	    padLeft = padRight = 30;
//	    offset = xoffset = yoffset = 30;
	    
//	    rows=20;
//	    columns=17;
	    
	    columns=rows=19;
	    
	    radius = (width - 2*padLeft)/(columns-1);
	    
	    offset = xoffset = yoffset = radius;
	    
	    Log.i("radius", radius + "");
	    
	    isPaint = null;   
	    pPoints = new ArrayList<PPoint>();   
	    pieces = new ArrayList<Piece>();	
	    delPoints = new ArrayList<PPoint>();
	    
	    matrix = new Point[rows][columns];
//	    temp = new int[rows][columns];  //-1黑 0未放1白
	    
	    for(int i = 0; i < rows; i++){
	    	for(int j = 0; j < columns; j++){
	    		matrix[i][j] = new Point();
	    		matrix[i][j].x = padLeft + j * offset;
	    		matrix[i][j].y = padTop + i * offset;
//	    		temp[i][j] = 0;
//	    		System.out.println(matrix[i][j].x + ":" + matrix[i][j].y);
	    	}
	    }
	}

	public MyImageView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		Log.i("MyImageView3", "3");
	}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		Log.i("MyImageView", "5");
		if(event.getAction() == MotionEvent.ACTION_MOVE) {
			down = true;
			x = event.getX() - padLeft;
			y = event.getY() - padTop;
			py = (int) (x / offset);
			if(x % offset > offset/2) py += 1;
			px = (int) (y / offset);
			if(y % offset > offset/2) px += 1;
			
			this.invalidate();//调用重绘
		}
		if(event.getAction() == MotionEvent.ACTION_DOWN) {
			down = true;
			x = event.getX() - padLeft;
			y = event.getY() - padTop;
			py = (int) (x / offset);
			if(x % offset > offset/2) py += 1;
			px = (int) (y / offset);
			if(y % offset > offset/2) px += 1;
			
			this.invalidate();//调用重绘
		}
		if(event.getAction() == MotionEvent.ACTION_UP) {
			down = false;
			x = event.getX() - padLeft;
			y = event.getY() - padTop;
			py = (int) (x / offset);
			if(x % offset > offset/2) py += 1;
			px = (int) (y / offset);
			if(y % offset > offset/2) px += 1;
			
			Log.d("XY", x + ":" + y);
			Log.d("PXY", px + ":" + py);
			
			//
			if (k % 2 != 0) {
				paint = wPaint;
			} else {
				paint = bPaint;
			}
			//检查是否出界
			if(CheckIndex(px,py)) {
				if(canDo(matrix[px][py])){
//					temp[px][py] = paint == wPaint ? 1 : -1;   //
					PPoint pPoint = new PPoint();
//					Piece nPiece = new Piece();
//					List<PPoint> lpPoint = new ArrayList<PPoint>();
					
					pPoint.setPoint(matrix[px][py]);
					pPoint.setPaint(paint);
					pPoint.setStep(k);
					pPoint.setValide(true);
					pPoint.setPieceId(k);
					pPoint.setEndStep(-1);
//					setLibertyAndPiece(pPoint,px,py);
//					pPoint.setLiberty(getLiberty(px,py));
					
					//是否可以下
					if(canGo(pPoints,pieces,pPoint)) {
						takes(pieces);
						modifyAllLiberty(pPoints);
						modifyPiecesLiberty(pieces);
						Log.i("points", pPoints.toArray().toString());
						k++;
						this.invalidate();//调用重绘
					}
				}
			}
		}
		return true;
	}
	    
	/**
	 * 
	* @Title: reBack
	* @Description: 回退操作,一部分是被合并掉了，一部分是被吃掉了,被吃掉的设为有效，被合并掉的恢复其块号
	* @param     设定文件
	* @return void    返回类型
	* @throws
	 */
	public void reBack() {
		if(k > 0) {
			k--;
			for(Piece pi: pieces) {
				//eat
				if(!pi.isValide() && pi.getEndStep() == k) {
					for(PPoint pp : pi.getPpoints()) {
						if(!pp.isValide()) {
							pp.setValide(true);
							pp.setEndStep(-1);
							delPoints.remove(pp);
						} else {
							//merged
							if(pp.getStep() != k) {
								pp.setPieceId(pi.getId());
							}
						}
					}
					pi.setValide(true);
					pi.setEndStep(-1);
				}
				
				if(pi.getId() == k) {
					pi.setValide(false);
					pieces.remove(pi);
				}
				
			}
			
			for(PPoint pp : pPoints) {
				if(pp.getStep() == k) {
					pp.setValide(false);
					pPoints.remove(pp);
				}
			}
			
			modifyAllLiberty(pPoints);
			modifyPiecesLiberty(pieces);
			this.invalidate();//调用重绘
		}
	}
	
	private void modifyPiecesLiberty(List<Piece> pieces2) {
		for(Piece pi : pieces2) {
			if(pi.isValide()) {
				pi.setTotalLiberty(getPieceLiberty(pi));
			}
		}
	}
	
	//获取块的气
	private int getPieceLiberty(Piece nPiece) {
		int lib = 0;
		if(nPiece != null){
			for(PPoint p : nPiece.getPpoints()) {
				if(p.isValide()) {
					lib += p.getLiberty();
				}
			}
		}
		return lib;
	}

	/**
	 * 
	* @Title: takes
	* @Description: 提子操作
	* @param @param pieces2    设定文件
	* @return void    返回类型
	* @throws
	 */
	private void takes(List<Piece> pieces2) {
		//劫的操作
		for(Piece pi : pieces2) {
			if(isKo && pi.getId() == k) {
				Log.i("KO", "It is ko ,can't delete the piece:" + pi.getId() + ":" + pi.getPpoints().size());
				continue;
			}
			if(pi.isValide()) {
				if(pi.getTotalLiberty() <= 0) {
					for(PPoint pp : pi.getPpoints()) {
						pp.setValide(false);
						pp.setEndStep(k);
						delPoints.add(pp);
					}
					pi.setValide(false);
					pi.setEndStep(k);
				}
			}
		}
	}

	//是否可下
	private boolean canGo(List<PPoint> pPoint,List<Piece> pieces,PPoint newPpoint) {
		boolean flag = false;
		
		Piece nPiece = new Piece();
		List<PPoint> lPpoint = new ArrayList<PPoint>();
		
		nPiece.setId(k);
		nPiece.setPaint(paint == wPaint ? 1 : -1);
		nPiece.setTotalLiberty(0);
		nPiece.setValide(true);
		nPiece.setPpoints(lPpoint);
		nPiece.setEndStep(-1);
		
		//合并块
		for(Piece pi : pieces) {
			if(pi.isValide()) {
				for(PPoint p1 : pi.getPpoints()) {
					if(isNeighbor(p1, newPpoint,1)) {
						merge(pi,nPiece);
						break;
					}
				}
			}
		}
		
		pPoint.add(newPpoint);
		modifyAllLiberty(pPoint);   
		
		//
		nPiece.getPpoints().add(newPpoint);
		nPiece.setTotalLiberty(getPieceLiberty(nPiece));
		
		//判断气为0，则删除该点，并重新计算各点的气
		// -----------修改，如果发现有其它块的气为零则表示可放--------
		isKo = false;
		modifyPiecesLiberty(pieces);
		for(Piece pi : pieces) {
			if(pi.isValide() && pi.getTotalLiberty() == 0 && pi.getPaint() != nPiece.getPaint()) {
				Log.i("TAG", pi.getId() + "");
				isKo = true;
				break;
			}
		}
		
		if(nPiece.getTotalLiberty() == 0) {
			
			if(isKo) {
				pieces.add(nPiece);
				for(PPoint p : nPiece.getPpoints()) {
					p.setPieceId(nPiece.getId());
				}
				flag = true;
			} else {
				pPoint.remove(newPpoint);
				modifyAllLiberty(pPoint);
				
				newPpoint.setValide(false);
				nPiece.getPpoints().remove(newPpoint);
				
				//该处有问题，这里只需要将上一步合并的块进行恢复，而不是将曾经合并的块一起恢复
				for(PPoint p : nPiece.getPpoints()) {
					if(p.getPieceId() != nPiece.getId()) {
						for(Piece pi : pieces) {
							if(p.getPieceId() == pi.getId()) {
								if(pi.isValide()) {
									//Log.e("ERROR", "");
								} else {
									pi.setValide(true);
									pi.setEndStep(-1);
								}
							}
						}
					}
				}
			}
		}
		//有效
		else if (nPiece.getTotalLiberty() > 0) {
			pieces.add(nPiece);
			for(PPoint p : nPiece.getPpoints()) {
				p.setPieceId(nPiece.getId());
			}
			flag = true; 
		}
		//更新块的气
		modifyPiecesLiberty(pieces);
		return flag;
	}
	
	/**
	* @Title: modifyAllLiberty
	* @Description: 更新所有点的气
	* @param     设定文件
	* @return void    返回类型
	* @throws
	*/ 
	private void modifyAllLiberty(List<PPoint> pPoints) {
		for(PPoint p : pPoints) {
			p.setLiberty(getLiberty(p));
		}
	}

	//合并块
	private void merge(Piece pi, Piece nPiece) {
		if(pi.getId() < nPiece.getId()) {
			for(PPoint pp : pi.getPpoints()){
				nPiece.getPpoints().add(pp);
			}
			nPiece.setValide(true);
			pi.setValide(false);
			pi.setEndStep(k);
		} else {
			Log.e("merge", "mergeError");
		}
	}
	
	
	//是否相邻，同颜色相邻  1：相同  2：不同    0，相邻
	private boolean isNeighbor(PPoint p1,PPoint p2,int same) {
		if(p1 != null && p2 !=null) {
			int p1x = p1.getPoint().x;
			int p1y = p1.getPoint().y;
			int p2x = p2.getPoint().x;
			int p2y = p2.getPoint().y;
			
			if(p1.isValide() && p2.isValide()) {
				if((p1y == p2y && Math.abs(p1x-p2x)==offset) || (p1x == p2x && Math.abs(p2y-p1y) == offset)) {
					if(same == 0) return true;
					if(p1.getPaint() == p2.getPaint() && same == 1) return true;
					if(p1.getPaint() != p2.getPaint() && same == 2) return true;
				}
			}
		}
		return false;
	}

	private int getLiberty(PPoint ppoint) {
		int liberty = 4;
		int px = ppoint.getPoint().y / offset;
		int py = ppoint.getPoint().x / offset;
		
		for(PPoint p : pPoints) {
			if(isNeighbor(p,ppoint,0)) liberty--;
		}
		
		if(px == 3) liberty--;
		if(px == rows-1) liberty--;
		if(py == 1) liberty--;
		if(py == columns-2) liberty--;
		
		Log.i("Liberty", liberty + "");
		return liberty;
	}
	
	//获取新下棋子的气    
	/**
	 * deprecated
	* @Title: getLiberty
	* @Description: TODO(这里用一句话描述这个方法的作用)
	* @param @param px
	* @param @param py
	* @param @return    设定文件
	* @return int    返回类型
	* @throws
	 */
	private int getLiberty(int px, int py) {
		// TODO Auto-generated method stub
		int liberty = 4;
		for(PPoint p : pPoints) {
			if(px > 3) {
				if(p.getPoint() == matrix[px-1][py] && p.isValide()) {
					liberty--;
					p.setLiberty(p.getLiberty()-1);
				}
			}
			if(px < rows -1) {
				if(p.getPoint() == matrix[px+1][py] && p.isValide()){
					liberty--;
					p.setLiberty(p.getLiberty()-1);
				}
			}
			if(py > 1) {
				if(p.getPoint() == matrix[px][py-1] && p.isValide()) {
					liberty--;
					p.setLiberty(p.getLiberty()-1);
				}
			}
			if(py < columns-2) {
				if(p.getPoint() == matrix[px][py+1] && p.isValide() ) {
					liberty--;
					p.setLiberty(p.getLiberty()-1);
				}
			}
		}
		if(px == 3) liberty--;
		if(px == rows-1) liberty--;
		if(py == 1) liberty--;
		if(py == columns-2) liberty--;
		
		Log.i("Liberty", liberty + "");
		return liberty;
	}

	@Override
	protected void onDraw(Canvas canvas) {
		Log.i("MyImageView", "4");
		super.onDraw(canvas);
		for(int i = 0; i < rows; i++) {
			//画横线
			canvas.drawLine(padLeft, i * offset + padTop, padLeft + (rows-1) * offset, i * offset + padTop, bPaint);
//			if(i*offset > width || i*offset > height) break;
//			canvas.drawLine(0, i * offset, width, i * offset, mPaint);
			//画竖线
//			canvas.drawLine(i * offset, 0, i * offset, height, mPaint);
//			canvas.drawLine(i * offset, padTop, i * offset, (float) (height - 2.5*padBottom), mPaint);
//			canvas.drawLine(i* offset, padTop, i * offset, 16 * offset + padTop,bPaint);
		} for(int j = 0; j < columns; j++) {
			canvas.drawLine(padLeft + j * offset, padTop, padLeft + j * offset, padTop + (columns-1) * offset,bPaint);
		}
//		canvas.drawCircle(x,y, radius, mPaint);
//		Log.d("matrixXY", matrix[px][py].  x + ":" + matrix[px][py].y);
//		canvas.drawCircle(matrix[px + 1][py + 1].x, matrix[px + 1][py + 1].y,    radius, mPaint);
		if(pPoints != null && pPoints.size() > 0){
			for(PPoint p : pPoints){
				if(p.isValide()) {
					
//					canvas.drawCircle(p.getPoint().x,p.getPoint().y,radius,p.getPaint());
//					Rect src = new Rect();// 图片
				    Rect dst = new Rect();// 屏幕
				    int bx = p.getPoint().x;
				    int by = p.getPoint().y;
				    dst.left = (int) (bx-radius/2);
				    dst.top = (int) (by-radius/2);
				    dst.right = (int) (bx + radius/2);
				    dst.bottom = (int) (by + radius/2);
				    if(Color.WHITE == p.getPaint().getColor()) canvas.drawBitmap(go_w, null, dst, null);
				    if(Color.BLACK == p.getPaint().getColor()) canvas.drawBitmap(go_b, null, dst, null);
//					canvas.drawText(p.getLiberty()+ ":" +p.getPieceId() , p.getPoint().x, p.getPoint().y, fPaint);
					Paint rPaint = new Paint();
					rPaint.setColor(p.getPaint().getColor());
					rPaint.setStyle(Paint.Style.STROKE);
//					canvas.drawCircle(p.getPoint().x, p.getPoint().y, radius + 4, rPaint);
				}
			}
		}
		
		if(down) {
//			canvas.drawCircle(py*offset, (px-4)*offset, radius, fPaint);
		}
	}
	
	//是否有子
	private boolean canDo(Point point){
		
		if(pPoints != null && pPoints.size() > 0){
			for(PPoint p : pPoints){
				if(p.isValide() && p.getPoint() == point) return false;
			}
		}
		return true;
	}
	
	//是否超界
	private boolean CheckIndex(int px, int py) {
		Log.i("PX:PY", px + ":" + py);
		if(px >= 0 && px < rows && py >= 0 && py < columns) return true;
		return false;
	}
	
	
}
